const Config = require('@/config/base_config');
const Storage = require('@/utils/storage')
const API_DOMAIN = Config.API_HOST;
const CACHE_EXPIRE_TIME=50000;

class RequestModel {
  constructor() {
    // 存储拦截器
    this.interceptors = {
      request: [], // 请求拦截器
      response: [] // 响应拦截器
    };
    this.pendingRequests = new Set();
  }
  async request(url, options = {}) {
    console.log(options)
    let config = {
      url,
      ...options
    };
    wx.showLoading({
      title: '',
    })
    const cacheKey = `req_${options.url}_${JSON.stringify(options.data)}`
    const cacheData = wx.getStorageSync(cacheKey)
    console.log("请求缓存：",cacheData);
    if (cacheData && Date.now() - cacheData.timestamp < CACHE_EXPIRE_TIME) {
      options.success && options.success(cacheData.data)
      return cacheData.data;
    }
    // 1. 执行请求拦截器
    try {
      for (const interceptor of this.interceptors.request) {
        config = await interceptor.fulfilled(config); // 只调用 fulfilled
      }
    } catch (error) {
      return Promise.reject(error);
    }
    const tmpUrl = `${API_DOMAIN}${url}`;
    return new Promise((resolve, reject) => {
      try {
        wx.request({
          header: {
            'content-type': 'application/json',
            'Authorization': `Bearer ${Storage.get("access_token") || ''}`,
            ...options.header
          },
          timeout: options.timeout || 3000,
          url: tmpUrl,
          method: options.method || 'GET',
          data: options.data || {},
          // 缓存相关配置
          enableCache: true, // 默认false，开启后可用缓存
          enableHttp2: true, // 开启 HTTP/2
          enableQuic: true, // 开启 QUIC
          success: (res) => {
            wx.setStorageSync(cacheKey, {
              data: res.data,
              timestamp: Date.now()
            })
            // 2. 响应拦截器
            let response = res;
            try {
              for (const interceptor of this.interceptors.response) {
                response = interceptor.fulfilled(response);
              }
              resolve(res.data);
            } catch (error) {
              reject(error);
            }
          },
          fail: (err) => {
            console.log(err)
            // 3. 错误拦截器
            let error = err;
            for (const interceptor of this.interceptors.response) {
              if (interceptor.rejected) {
                error = interceptor.rejected(error);
              }
            }
            reject(error);
          },
          complete: () => {
            wx.hideLoading()
          }
        });
      } catch (error) {
        console.error(error)
      }
    })
  }
  get(url, data, options) {
    console.log(data)
    return this.request(url, {
      method: 'GET',
      data,
      ...options
    });
  }
  post(url, data, options) {
    return this.request(url, {
      method: 'POST',
      data,
      ...options
    });
  }

  // 上传文件
  async upload(url, filePath, name, formData = {}, options = {}) {
    const requestKey = `upload_${url}_${filePath}`;
    this.pendingRequests.add(requestKey);
    // 请求拦截器处理
    let config = {
      url: `${API_DOMAIN}${url}`,
      filePath,
      name,
      formData,
      header: {
        'Authorization': `Bearer ${Storage.get('access_token') || ''}`,
        ...options.header
      },
      skipAuth: true,
      timeout: options.timeout || 60000
    };
    // 1. 执行请求拦截器
    try {
      for (const interceptor of this.interceptors.request) {
        config = await interceptor.fulfilled(config); // 只调用 fulfilled
      }
    } catch (error) {
      return Promise.reject(error);
    }
    return new Promise((resolve, reject) => {
      wx.showLoading({
        title: '',
      })

      wx.uploadFile({
        url: `${API_DOMAIN}${url}`,
        filePath,
        name,
        formData,
        header: {
          'Authorization': `Bearer ${Storage.get('access_token') || ''}`,
          ...options.header
        },
        success: (res) => {
          try {
            const data = res.statusCode === 200 ? JSON.parse(res.data) : res.data;
            if (res.statusCode === 200) {
              resolve(data);
            } else {
              this.handleHttpError(res.statusCode);
              reject(data);
            }
          } catch (e) {
            reject(e);
          }
        },
        fail: (err) => {
          this.handleRequestError(err);
          reject(err);
        },
        complete: () => {
          this.pendingRequests.delete(requestKey);
          wx.hideLoading();
          if (this.loadingTimer) {
            clearTimeout(this.loadingTimer);
            this.loadingTimer = null;
          }
        }
      });

    });
  }


  // 检查Token是否即将过期（提前5分钟检查）
  isTokenExpiringSoon() {
    const token = Storage.get('access_token');
    console.log(token)
    if (!token) return true;

    try {
      // 小程序环境可能需要使用wx.base64ToArrayBuffer
      const payloadBase64 = token.split('.')[1];
      const payloadJson = decodeURIComponent(
        atob(payloadBase64)
        .split('')
        .map(c => '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2))
        .join('')
      );
      const payload = JSON.parse(payloadJson);

      if (payload.exp && typeof payload.exp === 'number') {
        // 提前5分钟检查
        return payload.exp * 1000 - Date.now() < 5 * 60 * 1000;
      }
      return true;
    } catch (e) {
      return true;
    }
  }
  /**
   * 刷新Token
   * @returns {Promise<string|null>} 返回新的token或null
   */
  async refreshToken() {
    if (this.isRefreshing) {
      return new Promise((resolve) => {
        this.requestsQueue.push(resolve);
      });
    }

    try {
      this.isRefreshing = true;
      const refreshToken = Storage.get('refresh_token');
      console.log("refreshToken", refreshToken)
      if (!refreshToken) {
        console.error('缺少refreshToken');
        // --登录过期，直接跳转登录页面
        this.redirectToLogin();
        throw {
          code: 401,
          message: '登录已过期，请重新登录',
          config: response.config
        };
      }
      await refreshAccessToken(refreshToken).then((response) => {
        try {
          if (!response.data?.access_token) {
            throw new Error('无效的Token响应');
          }

          let expires_in = Util.timeToSeconds(response.data.expires_in);
          Storage.set('access_token', response.data.access_token, expires_in);

          this.requestsQueue.forEach(cb => cb(response.data.access_token));
          this.requestsQueue = [];

          return response.data.access_token;
        } catch (error) {
          throw new Error(error)
          return null;
        }
      });
    } catch (error) {
      console.log('刷新Token失败:', error);

      Storage.remove('access_token');
      Storage.remove('refresh_token');
      this.requestsQueue.forEach(cb => cb(null));
      this.requestsQueue = [];

      return null;
    } finally {
      this.isRefreshing = false;
    }
  }
  redirectToLogin() {
    setTimeout(() => {
      const pages = getCurrentPages();
      const currentPage = pages[pages.length - 1];
      const currentRoute = currentPage.route;
      const currentOptions = currentPage.options || {};
      console.log(`/pages/login/index?redirect=${encodeURIComponent(currentRoute)}&params=${encodeURIComponent(JSON.stringify(currentOptions))}`)
      wx.redirectTo({
        url: `/pages/login/index?redirect=${encodeURIComponent(currentRoute)}&params=${encodeURIComponent(JSON.stringify(currentOptions))}`
      });
    }, 1500);
  }
  async handleRequestError(error) {
    // 确保loading被清除
    wx.hideLoading();
    if (this.loadingTimer) {
      clearTimeout(this.loadingTimer);
      this.loadingTimer = null;
    }

    if (error.type === 'http') {
      this.handleHttpError(error.statusCode);
    } else if (error.type === 'token_expired') {
      wx.showToast({
        title: error.message || '登录已过期',
        icon: 'none',
        duration: 2000
      });
      setTimeout(() => {
        this.clearUserData();
        this.navigateToLogin();
      }, 2000);
    } else {
      wx.showToast({
        title: error.message || '请求失败',
        icon: 'none',
        duration: 2000
      });
    }
  }

  // 添加请求拦截器
  addRequestInterceptor(fulfilled, rejected) {
    console.log("响应前拦截")
    this.interceptors.request.push({
      fulfilled,
      rejected: rejected || (error => Promise.reject(error))
    });
  }

  // 添加响应拦截器
  addResponseInterceptor(fulfilled, rejected) {
    console.log("响应前拦截")
    this.interceptors.response.push({
      fulfilled,
      rejected: rejected || (error => Promise.reject(error))
    });
  }

  // 清空拦截器
  static clearInterceptors() {
    this.interceptors.request = [];
    this.interceptors.response = [];
  }
}
export default RequestModel;